/*
Copyright (C) 1996-1997 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

// refresh.h -- public interface to refresh functions

#pragma once

#define	MAXCLIPPLANES	11

#define	TOP_RANGE		16			// soldier uniform colors
#define	BOTTOM_RANGE	96

//=============================================================================

struct efrag_t
{
	struct mleaf_t		*leaf;
	struct entity_t		*entity;
	efrag_t		*leafnext;
	efrag_t		*entnext;
};


#define LERP_MOVESTEP	(1 << 0) // this is a MOVETYPE_STEP entity, enable movement lerp
#define LERP_RESETANIM	(1 << 1) // disable anim lerping until next anim frame
#define LERP_RESETANIM2	(1 << 2) // set this and previous flag to disable anim lerping for two anim frames
#define LERP_RESETMOVE	(1 << 3) // disable movement lerping until next origin/angles change
#define LERP_FINISH		(1 << 4) // use lerpfinish time from server update instead of assuming interval of 0.1
#define LERP_STEPZ		(1 << 5) // don't anim lerp in z
#define LERP_RESETALL	(LERP_RESETANIM | LERP_RESETANIM2 | LERP_RESETMOVE)


struct lightpoint_t
{
	byte lightmap[MAX_SURFACESTYLES][3];
	byte lightstyles[MAX_SURFACESTYLES];
};


struct entity_t
{
	// storing the local matrix for the entity in it's own struct
	QMATRIX			entitymatrix;	// the entity's position in world space
	QMATRIX			localmatrix;	// the entity's position in local space

	// computed bounding box and midpoint
	bbox_t			bbox;

	// true if the entity has been culled by R_CullBox, false otherwise, used for
	// drawing shadows for entitys outside of the view frustum (of course the shadow may also be
	// outside but that's another problem entirely, isn't it?)
	BOOL			culled;

	// drawing flags for brushmodel entities
	int				drawflags;

	int				entitynum;

	BOOL			forcelink;		// model changed

	entity_state_t	baseline;		// to fill in defaults in updates

	// rockettrails
	vec3_t			oldtrailorigin;
	double			nexttrailtime;

	// alpha
	float			alpha;

	double			msgtime;		// time of last update
	vec3_t			msg_origins[2];	// last two updates (0 is newest)
	vec3_t			origin;
	vec3_t			msg_angles[2];	// last two updates (0 is newest)
	vec3_t			angles;
	struct model_t	*model;			// NULL = no model
	struct efrag_t	*efrag;			// linked list of efrags
	int				frame;
	float			syncbase;		// for client-side animations
	byte			*colormap;
	int				effects;		// light, particals, etc
	int				skinnum;		// for Alias models
	int				visframe;		// last frame this entity was found in an active leaf

	// inverse transform of entity for backfacing stuff
	float			modelorg[3];

	// lerping info
	byte			lerpflags;		// lerping
	double			lerpstart;		// animation lerping
	double			lerpfinish;		// lerping -- server sent us a more accurate interval, use it instead of 0.1

	short			prevpose;	// animation lerping
	short			currpose;	// animation lerping
	float			poseblend;	// animation lerping

	double			originlerpstart[3];	// transform lerping
	double			angleslerpstart[3];	// transform lerping

	vec3_t			prevorigin;	// transform lerping
	vec3_t			currorigin;	// transform lerping
	vec3_t			lerporigin;	// transform lerping

	vec3_t			prevangles;	// transform lerping
	vec3_t			currangles;	// transform lerping
	vec3_t			lerpangles;	// transform lerping

	// lighting
	lightpoint_t	lightpoint;
	float			shadelight[3];
	float			shadevector[3];

	// because some object types can be multipassed, there is certain info we don't want to reset on
	// passes subsequent to the first, so this serves as a hint to not do so
	int				PassNum;
};


void R_LightPoint (vec3_t p, lightpoint_t *lightpoint);
void R_LightPointToShadeLight (lightpoint_t *lightpoint, float *shadelight);

// !!! if this is changed, it must be changed in asm_draw.h too !!!
typedef struct refdef_s
{
	float		ViewOrigin[3];
	float		ViewAngles[3];

	// world matrixes
	QMATRIX		ProjectionMatrix;
	QMATRIX		ViewMatrix;
	QMATRIX		MVPMatrix;
	QMATRIX		InverseViewProj;

	// current rendertarget
	QTEXTURE	*RenderTarget;

	mplane_t	Frustum[4];

	float		FovX;
	float		FovY;

	int			FrameCount;
	int			VisFrameCount;
	int			LightPass;

	// because these object types can be multipassed, there is certain info we don't want to reset on
	// passes subsequent to the first, so this serves as a hint to not do so
	int			AliasPasses;
	int			BrushPasses;

	// current view leafs; 0 is most recent
	struct		mleaf_t *ViewLeaf[3];

	// current texture for water tinting
	struct		texture_t *WaterTexture;
} refdef_t;


// refresh
extern	int		reinit_surfcache;


extern	refdef_t	ref;


void R_Init (void);
void R_InitEfrags (void);
void R_RenderView (void);		// must set ref first
void R_InitSky (struct miptex_s *mt, byte *texels);	// called at level load

void R_AddEfrags (entity_t *ent);
void R_StoreEfrags (efrag_t **ppefrag);

void R_NewMap (void);


#define RT_ROCKETTRAIL		0
#define RT_SMOKETRAIL		1
#define RT_BLOOD			2
#define RT_TRACERWIZARD		3
#define RT_SLIGHTBLOOD		4
#define RT_TRACERKNIGGIT	5
#define RT_TRACERVORE		6

void R_ParseParticleEffect (void);
void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count);
void R_RocketTrail (float *start, float *end, int type);

void R_EntityParticles (entity_t *ent);
void R_BlobExplosion (vec3_t org);
void R_ParticleExplosion (vec3_t org);
void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength);
void R_LavaSplash (vec3_t org);
void R_TeleportSplash (vec3_t org);


